import pygame
import numpy as np
import sys
import math
from pygame.locals import *

# 初始化Pygame
pygame.init()

# 设置窗口
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("飞鸟与月食")

# 确保中文正常显示
pygame.font.init()
font_options = ["AR PL UKai CN"]
font = None
for font_name in font_options:
    try:
        font = pygame.font.SysFont(font_name, 30)
        if font:
            break
    except:
        continue
if not font:
    font = pygame.font.SysFont(None, 30)  #  fallback

# 颜色设置
SKY_COLORS = {
    "night": (10, 10, 40),       # 夜晚
    "sunrise": (255, 180, 120),  # 日出
    "day": (135, 206, 235),      # 白天
    "sunset": (255, 140, 60)     # 日落
}
SUN_COLOR = (255, 215, 0)       # 太阳颜色（金黄色）
SUN_GLOW = (255, 165, 0, 128)   # 太阳光晕（半透明）
MOON_COLOR = (240, 240, 240)    # 月亮颜色（银白色）
MOON_GLOW = (255, 255, 255, 64) # 月亮光晕
ECLIPSE_COLOR = (40, 40, 60)    # 月食阴影颜色（暗红色）

# 鸟的类
class Bird:
    def __init__(self):
        # 初始随机颜色
        self.body_color = tuple(np.random.randint(50, 200, 3))
        self.wing_color = tuple(np.random.randint(50, 200, 3))
        self.beak_color = (255, 165, 0)  # 喙的颜色固定为橙色
        
        # 位置和速度
        self.x = -50  # 从屏幕左侧外开始
        self.y = np.random.randint(100, HEIGHT - 100)
        self.speed = np.random.uniform(2, 5)
        
        # 翅膀动画参数
        self.wing_angle = 0
        self.wing_speed = np.random.uniform(0.1, 0.3)
        self.wing_direction = 1
        
        # 颜色变化参数
        self.color_change_interval = np.random.randint(30, 60)  # 颜色变化间隔（帧）
        self.color_change_counter = 0  # 颜色变化计数器
    
    def update(self):
        # 更新位置
        self.x += self.speed
        if self.x > WIDTH + 50:  # 飞出屏幕后重置
            self.x = -50
            self.y = np.random.randint(100, HEIGHT - 100)
            self.speed = np.random.uniform(2, 5)
        
        # 更新翅膀角度（扇动效果）
        self.wing_angle += self.wing_speed * self.wing_direction
        if self.wing_angle > 0.8:
            self.wing_direction = -1
        elif self.wing_angle < -0.4:
            self.wing_direction = 1
        
        # 颜色变化逻辑
        self.color_change_counter += 1
        if self.color_change_counter >= self.color_change_interval:
            # 随机改变身体和翅膀颜色
            self.body_color = tuple(np.random.randint(50, 200, 3))
            self.wing_color = tuple(np.random.randint(50, 200, 3))
            # 重置计数器并随机下次变化间隔
            self.color_change_counter = 0
            self.color_change_interval = np.random.randint(30, 60)
    
    def draw(self, surface):
        # 绘制身体（椭圆）
        body_rect = pygame.Rect(0, 0, 60, 30)
        body_rect.center = (self.x, self.y)
        pygame.draw.ellipse(surface, self.body_color, body_rect)
        
        # 绘制头部（圆形）
        head_radius = 15
        pygame.draw.circle(surface, self.body_color, 
                          (int(self.x + 30), self.y), head_radius)
        
        # 绘制眼睛
        eye_pos = (int(self.x + 35), self.y - 5)
        pygame.draw.circle(surface, (0, 0, 0), eye_pos, 3)
        
        # 绘制喙（三角形）
        beak_points = [
            (self.x + 40, self.y),
            (self.x + 50, self.y - 3),
            (self.x + 50, self.y + 3)
        ]
        pygame.draw.polygon(surface, self.beak_color, beak_points)
        
        # 绘制翅膀（根据角度变化）
        wing_angle = self.wing_angle
        wing_points = [
            (self.x, self.y),
            (self.x - 30 * np.cos(wing_angle + np.pi/4), 
             self.y - 30 * np.sin(wing_angle + np.pi/4)),
            (self.x - 20 * np.cos(wing_angle - np.pi/4), 
             self.y + 20 * np.sin(wing_angle - np.pi/4))
        ]
        pygame.draw.polygon(surface, self.wing_color, wing_points)
        
        # 绘制尾巴
        tail_points = [
            (self.x - 30, self.y - 10),
            (self.x - 50, self.y),
            (self.x - 30, self.y + 10)
        ]
        pygame.draw.polygon(surface, self.body_color, tail_points)

# 创建鸟实例
bird = Bird()

# 太阳和月亮动画控制
sun_radius = 40
moon_radius = 30
day_cycle = 4000  # 日出日落周期（帧数）
eclipse_cycle = 8000  # 月食周期（帧数，约133秒）
time_counter = 0

def get_sky_color(time):
    """根据时间获取天空颜色"""
    phase = (time % day_cycle) / day_cycle  # 0-1之间的周期值
    
    if phase < 0.2:  # 夜晚 (0-0.2)
        return SKY_COLORS["night"]
    elif phase < 0.3:  # 日出过渡 (0.2-0.3)
        t = (phase - 0.2) / 0.1
        return (
            int(SKY_COLORS["night"][0]*(1-t) + SKY_COLORS["sunrise"][0]*t),
            int(SKY_COLORS["night"][1]*(1-t) + SKY_COLORS["sunrise"][1]*t),
            int(SKY_COLORS["night"][2]*(1-t) + SKY_COLORS["sunrise"][2]*t)
        )
    elif phase < 0.6:  # 白天 (0.3-0.6)
        return SKY_COLORS["day"]
    elif phase < 0.7:  # 日落过渡 (0.6-0.7)
        t = (phase - 0.6) / 0.1
        return (
            int(SKY_COLORS["day"][0]*(1-t) + SKY_COLORS["sunset"][0]*t),
            int(SKY_COLORS["day"][1]*(1-t) + SKY_COLORS["sunset"][1]*t),
            int(SKY_COLORS["day"][2]*(1-t) + SKY_COLORS["sunset"][2]*t)
        )
    else:  # 夜晚过渡 (0.7-1.0)
        t = (phase - 0.7) / 0.3
        return (
            int(SKY_COLORS["sunset"][0]*(1-t) + SKY_COLORS["night"][0]*t),
            int(SKY_COLORS["sunset"][1]*(1-t) + SKY_COLORS["night"][1]*t),
            int(SKY_COLORS["sunset"][2]*(1-t) + SKY_COLORS["night"][2]*t)
        )

def get_sun_position(time):
    """计算太阳位置（模拟日出日落轨迹）"""
    phase = (time % day_cycle) / day_cycle
    angle = phase * 2 * math.pi - math.pi/2  # 角度从-90°到270°
    
    # 太阳轨迹：使用正弦曲线模拟弧形轨迹
    x = WIDTH * phase
    # 垂直位置：中间低（正午），两边高（日出日落）
    y = HEIGHT/3 - math.sin(angle) * HEIGHT/4
    
    # 限制太阳在可见范围内
    if y < sun_radius:
        y = sun_radius
    if y > HEIGHT - sun_radius:
        y = HEIGHT - sun_radius
        
    return (x, y)

def get_moon_position_and_eclipse(time):
    """计算月亮位置和月食程度"""
    # 月亮位置（与太阳轨迹相反）
    phase = (time % day_cycle) / day_cycle
    angle = (phase + 0.5) * 2 * math.pi - math.pi/2  # 与太阳位置相反
    x = WIDTH * (1 - phase)  # 从右侧向左侧移动（与太阳相反）
    y = HEIGHT/4 - math.sin(angle) * HEIGHT/5  # 月亮轨迹略高于太阳
    
    # 月食相位（0-1-0，0表示无月食，1表示全食）
    eclipse_phase = (time % eclipse_cycle) / eclipse_cycle
    if eclipse_phase < 0.25:
        # 偏食阶段（逐渐被遮挡）
        eclipse_factor = eclipse_phase / 0.25
    elif eclipse_phase < 0.5:
        # 全食阶段
        eclipse_factor = 1.0
    elif eclipse_phase < 0.75:
        # 偏食阶段（逐渐恢复）
        eclipse_factor = 1 - (eclipse_phase - 0.5) / 0.25
    else:
        # 无月食阶段
        eclipse_factor = 0.0
    
    # 限制月亮在可见范围内
    if y < moon_radius:
        y = moon_radius
    if y > HEIGHT - moon_radius:
        y = HEIGHT - moon_radius
        
    return (x, y, eclipse_factor)

# 主循环
clock = pygame.time.Clock()
running = True

while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
    
    # 更新计数器
    time_counter += 1
    
    # 绘制天空背景
    sky_color = get_sky_color(time_counter)
    screen.fill(sky_color)
    
    # 绘制太阳和光晕（只在白天显示）
    sun_phase = (time_counter % day_cycle) / day_cycle
    if 0.2 < sun_phase < 0.7:  # 白天时段显示太阳
        sun_x, sun_y = get_sun_position(time_counter)
        # 绘制太阳光晕
        glow_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        pygame.draw.circle(glow_surface, SUN_GLOW, (int(sun_x), int(sun_y)), sun_radius + 20)
        screen.blit(glow_surface, (0, 0))
        # 绘制太阳
        pygame.draw.circle(screen, SUN_COLOR, (int(sun_x), int(sun_y)), sun_radius)
    
    # 绘制月亮和月食（只在夜晚显示）
    if not (0.2 < sun_phase < 0.7):  # 夜晚时段显示月亮
        moon_x, moon_y, eclipse_factor = get_moon_position_and_eclipse(time_counter)
        
        # 绘制月亮光晕
        glow_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        pygame.draw.circle(glow_surface, MOON_GLOW, (int(moon_x), int(moon_y)), moon_radius + 15)
        screen.blit(glow_surface, (0, 0))
        
        # 绘制完整月亮
        pygame.draw.circle(screen, MOON_COLOR, (int(moon_x), int(moon_y)), moon_radius)
        
        # 绘制月食阴影（根据月食程度）
        if eclipse_factor > 0:
            # 阴影位置：从右侧向左侧移动
            shadow_offset = int((eclipse_factor - 0.5) * 2 * moon_radius * 0.8)
            eclipse_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            pygame.draw.circle(
                eclipse_surface, 
                ECLIPSE_COLOR, 
                (int(moon_x) + shadow_offset, int(moon_y)), 
                moon_radius
            )
            screen.blit(eclipse_surface, (0, 0))
    
    # 更新和绘制鸟
    bird.update()
    bird.draw(screen)
    
    # 显示说明文字
    text = font.render("飞鸟与月食（按ESC退出）", True, (255, 255, 255))
    screen.blit(text, (10, 10))
    
    # 刷新屏幕
    pygame.display.flip()
    
    # 控制帧率
    clock.tick(60)
    
    # 检测ESC键退出
    keys = pygame.key.get_pressed()
    if keys[K_ESCAPE]:
        running = False

pygame.quit()
sys.exit()

